/* app_fir_convolution_example */

#include "app.h"
#include "app_fir_data.h"


/*******************************************************************************
 * Definitions
 ******************************************************************************/

/*******************************************************************************
 * Variables
 ******************************************************************************/

/*******************************************************************************
 * Prototypes
 ******************************************************************************/

/*******************************************************************************
 * Code
 ******************************************************************************/

void app_arm_convolution_f32_example(void)
{
    PRINTF("%s()\r\n", __func__);

    /* 清零输出队列 */
    memset(fir_output_y_f32, 0, sizeof(float32_t) * FIR_CONV_OUTPUT_NUM );
    /*
    [in]  *pSrcApoints to the first input sequence.
    [in]  srcALenlength of the first input sequence.
    [in]  *pSrcBpoints to the second input sequence.
    [in]  srcBLenlength of the second input sequence.
    [out] *pDstpoints to the location where the output result is written. Length srcALen+srcBLen-1.
    */
    TimerCount_Start(); /* 开始计时. */
    arm_conv_f32(   fir_input_x_f32, FIR_INPUT_NUM,
                    fir_coeff_b_f32, FIR_COEFF_NUM,
                    fir_output_y_f32 );
    TimerCount_Stop(tick_counter_val); /* 结束计时. */

    /* 打印最终结果. */
    for (uint32_t i = 0; i < FIR_CONV_OUTPUT_NUM; i++)
    {
        PRINTF("[%4d]: %f\r\n", i, fir_output_y_f32[i]);
    }
    PRINTF("done with %d us.\r\n\r\n", tick_counter_val/96u); /* 打印计算时间. */
}

/* 重新封装的使用PQ计算卷积的驱动函数. */
void PQ_Convolution(POWERQUAD_Type *base,
       void *pAData, int32_t ALength,
       void *pBData, int32_t BLength,
       void *pResult)
{
    PQ_FIR(base, pAData, ALength, pBData, BLength, pResult, PQ_FIR_CONVOLUTION);
}

void app_pq_convolution_f32_example(void)
{
    PRINTF("%s()\r\n", __func__);

    /* 清零输出队列 */
    memset(fir_output_y_f32, 0, sizeof(float32_t) * FIR_CONV_OUTPUT_NUM );

    /* 设定浮点数计算. */
    PQ_SetFormat(POWERQUAD, kPQ_CP_FIR, kPQ_Float);

    /* 计算卷积. */
    TimerCount_Start(); /* 开始计时. */
    PQ_Convolution(POWERQUAD,
        fir_input_x_f32, FIR_INPUT_NUM,
        fir_coeff_b_f32, FIR_COEFF_NUM,
        fir_output_y_f32);
    PQ_WaitDone(POWERQUAD);
    TimerCount_Stop(tick_counter_val); /* 结束计时. */

    /* 打印最终结果. */
    for (uint32_t i = 0; i < FIR_CONV_OUTPUT_NUM; i++)
    {
        PRINTF("[%4d]: %f\r\n", i, fir_output_y_f32[i]);
    }
    PRINTF("done with %d us.\r\n\r\n", tick_counter_val/96u); /* 打印计算时间. */
}

/* 基于app_pq_correlation_f32_example()
 * 将b[m]队列预先存入private ram, 通过并行IO提高整体的处理时间.
 * 本例主要验证计算结果的正确性.
 * 本例的数据规模很小, 所以加速的效果不明显, 在大计算量时将会体现出加速优势.
 */

#define PQ_PRIVATE_RAM_0_BASE 0xe0000000 /* + 0 */
#define PQ_PRIVATE_RAM_1_BASE 0xe0001000 /* + 4KB. LPC5500有16KB, RT600有8KB. */

void app_pq_convolution_f32_example_2(void)
{
    PRINTF("%s()\r\n", __func__);

    /* 清零输出队列 */
    memset(fir_output_y_f32, 0, sizeof(float32_t) * FIR_CONV_OUTPUT_NUM );

    /* 设定浮点数计算. */
    PQ_SetFormat(POWERQUAD, kPQ_CP_FIR, kPQ_Float);

    /* 先把b[m]复制到PowerQuad的private ram. */
    PQ_MatrixScale(POWERQUAD, FIR_COEFF_NUM, 1.0f, fir_coeff_b_f32, (void *)PQ_PRIVATE_RAM_1_BASE);

    /* 计算卷积. */
    TimerCount_Start();
    PQ_Convolution(POWERQUAD,
        fir_input_x_f32, FIR_INPUT_NUM,
        (void *)PQ_PRIVATE_RAM_1_BASE, FIR_COEFF_NUM, /* 同private ram里的b[m]计算 */
        fir_output_y_f32);
    PQ_WaitDone(POWERQUAD);
    TimerCount_Stop(tick_counter_val);

    /* 打印最终结果. */
    for (uint32_t i = 0; i < FIR_CONV_OUTPUT_NUM; i++)
    {
        PRINTF("[%4d]: %f\r\n", i, fir_output_y_f32[i]);
    }
    PRINTF("done with %d us.\r\n\r\n", tick_counter_val/96u);
}

/* EOF. */

